package com.moshme.web.controller.project;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.moshme.common.constant.FeiJuProject;
import com.moshme.common.core.domain.entity.SysUser;
import com.moshme.common.utils.StringUtils;
import com.moshme.project.domain.ProjectStep;
import com.moshme.project.domain.StageCheckFile;
import com.moshme.project.domain.StageConstruct;
import com.moshme.project.service.*;
import com.moshme.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.moshme.common.annotation.Log;
import com.moshme.common.core.controller.BaseController;
import com.moshme.common.core.domain.AjaxResult;
import com.moshme.common.enums.BusinessType;
import com.moshme.project.domain.ProjectInfo;
import com.moshme.common.utils.poi.ExcelUtil;
import com.moshme.common.core.page.TableDataInfo;

/**
 * 项目信息Controller
 *
 * @author 望夜
 * @date 2023-08-11
 */
@RestController
@RequestMapping("/project/info")
@Api("项目信息")
public class ProjectInfoController extends BaseController {
    @Autowired
    private ProjectInfoService projectInfoService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ProjectStepService projectStepService;
    @Autowired
    private ProjectStepUserService projectStepUserService;
    @Autowired
    private StageSurveyService stageSurveyService;
    @Autowired
    private StageConstructService constructService;
    @Autowired
    private StageCheckController checkController;
    @Autowired
    private StageCheckFileService checkFileService;


    /**
     * 查询项目信息列表
     */
    @PreAuthorize("@ss.hasPermi('project:info:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询项目信息列表")
    public TableDataInfo list(ProjectInfo projectInfo) {
        startPage();
        List<ProjectInfo> list = projectInfoService.selectProjectInfoList(projectInfo);

        return getDataTable(list);
    }

    /**
     * 导出项目信息列表
     */
    @PreAuthorize("@ss.hasPermi('project:info:export')")
    @Log(title = "项目信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation(value = "导出项目信息列表")
    public void export(HttpServletResponse response, ProjectInfo projectInfo) {
        List<ProjectInfo> list = projectInfoService.selectProjectInfoList(projectInfo);
        ExcelUtil<ProjectInfo> util = new ExcelUtil<ProjectInfo>(ProjectInfo.class);
        util.exportExcel(response, list, "项目信息数据");
    }

    /**
     * 获取项目信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('project:info:query')")
    @GetMapping(value = {"/", "/{projectId}"})
    @ApiOperation(value = "获取项目信息")
    public AjaxResult getInfo(@PathVariable(value = "projectId", required = false) Long projectId) {
        AjaxResult ajax = AjaxResult.success();

        List<SysUser> sysUsers = userService.selectUserAll();
        ajax.put("users", sysUsers);

        if (StringUtils.isNotNull(projectId)) {
            ProjectInfo projectInfo = projectInfoService.selectProjectInfoByProjectId(projectId);
            ajax.put(AjaxResult.DATA_TAG, projectInfo);
            List<Long> userIds = userService.selectUserIdsByProjectId(projectId);
            ajax.put("userIds", userIds);
            //传sysUsers包含userIds的集合
            List<SysUser> collect = sysUsers.stream()
                    .filter(user -> userIds.contains(user.getUserId()))
                    .collect(Collectors.toList());
            ajax.put("stepUsers", collect);

            LambdaQueryWrapper<ProjectStep> dockWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.DJ.getValue());
            ProjectStep dockStep = projectStepService.getOne(dockWrapper);
            if (StringUtils.isNotNull(dockStep)) {
                dockStep = setStep(dockStep);
                ajax.put("dock", dockStep);
            }
            LambdaQueryWrapper<ProjectStep> kcWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.KC.getValue());
            ProjectStep kcStep = projectStepService.getOne(kcWrapper);
            if (StringUtils.isNotNull(kcStep)) {
                kcStep = setStep(kcStep);
                ajax.put("kc", kcStep);
            }
            LambdaQueryWrapper<ProjectStep> fhbzWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.FABZ.getValue());
            ProjectStep fhbzStep = projectStepService.getOne(fhbzWrapper);
            if (StringUtils.isNotNull(fhbzStep)) {
                fhbzStep = setStep(fhbzStep);
                ajax.put("fabz", fhbzStep);
            }
            LambdaQueryWrapper<ProjectStep> fhhbWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.FAHB.getValue());
            ProjectStep fhhbStep = projectStepService.getOne(fhhbWrapper);
            if (StringUtils.isNotNull(fhhbStep)) {
                fhhbStep = setStep(fhhbStep);
                ajax.put("fahb", fhhbStep);
            }
            LambdaQueryWrapper<ProjectStep> bjWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.BJ.getValue());
            ProjectStep bjStep = projectStepService.getOne(bjWrapper);
            if (StringUtils.isNotNull(bjStep)) {
                bjStep = setStep(bjStep);
                ajax.put("bj", bjStep);
            }
            LambdaQueryWrapper<ProjectStep> sgWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.SG.getValue());
            ProjectStep sgStep = projectStepService.getOne(sgWrapper);
            if (StringUtils.isNotNull(sgStep)) {
                sgStep = setStep(sgStep);
                ajax.put("sg", sgStep);
            }
            LambdaQueryWrapper<ProjectStep> ysWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.YS.getValue());
            ProjectStep ysStep = projectStepService.getOne(ysWrapper);
            if (StringUtils.isNotNull(ysStep)) {
                ysStep = setStep(ysStep);
                ajax.put("ys", ysStep);
            }
            LambdaQueryWrapper<ProjectStep> htqdWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.HTQD.getValue());
            ProjectStep htqdStep = projectStepService.getOne(htqdWrapper);
            if (StringUtils.isNotNull(htqdStep)) {
                htqdStep = setStep(htqdStep);
                ajax.put("htqd", htqdStep);
            }

        }

        return ajax;
    }

    /**
     * 新增项目信息
     */
    @PreAuthorize("@ss.hasPermi('project:info:add')")
    @Log(title = "项目信息", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation(value = "新增项目信息")
    public AjaxResult add(@RequestBody @Validated ProjectInfo projectInfo) {
        projectInfo.setProjectStep(FeiJuProject.DJ.getValue());
        return toAjax(projectInfoService.insertProjectInfo(projectInfo));
    }

    /**
     * 修改项目信息
     */
    @PreAuthorize("@ss.hasPermi('project:info:edit')")
    @Log(title = "项目信息", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation(value = "修改项目信息")
    public AjaxResult edit(@RequestBody @Validated ProjectInfo projectInfo) {
        Long projectId = projectInfo.getProjectId();
        Long[] userIds = projectInfo.getUserIds();
        HashSet<Long> userSet = new HashSet<>();
        for (Long userId : userIds) {
            userSet.add(userId);
        }
        HashSet<Long> set = new HashSet<>();

        LambdaQueryWrapper<ProjectStep> dockWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.DJ.getValue());
        ProjectStep dockStep = projectStepService.getOne(dockWrapper);
        if (StringUtils.isNotNull(dockStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(dockStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> kcWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.KC.getValue());
        ProjectStep kcStep = projectStepService.getOne(kcWrapper);
        if (StringUtils.isNotNull(kcStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(kcStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> fhbzWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.FABZ.getValue());
        ProjectStep fhbzStep = projectStepService.getOne(fhbzWrapper);
        if (StringUtils.isNotNull(fhbzStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(fhbzStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> fhhbWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.FAHB.getValue());
        ProjectStep fhhbStep = projectStepService.getOne(fhhbWrapper);
        if (StringUtils.isNotNull(fhhbStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(fhhbStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> bjWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.BJ.getValue());
        ProjectStep bjStep = projectStepService.getOne(bjWrapper);
        if (StringUtils.isNotNull(bjStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(bjStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> sgWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.SG.getValue());
        ProjectStep sgStep = projectStepService.getOne(sgWrapper);
        if (StringUtils.isNotNull(sgStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(sgStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> ysWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.YS.getValue());
        ProjectStep ysStep = projectStepService.getOne(ysWrapper);
        if (StringUtils.isNotNull(ysStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(ysStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }
        LambdaQueryWrapper<ProjectStep> htqdWrapper = new LambdaQueryWrapper<ProjectStep>().eq(ProjectStep::getProjectId, projectId).eq(ProjectStep::getProjectStep, FeiJuProject.HTQD.getValue());
        ProjectStep htqdStep = projectStepService.getOne(htqdWrapper);
        if (StringUtils.isNotNull(htqdStep)) {
            Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(htqdStep.getStepId());
            for (Long stepUserId : stepUserIds) {
                set.add(stepUserId);
            }
        }

        for (Long id : set) {
            if (!userSet.contains(id)) {
                return AjaxResult.error("请先删除该项目子阶段的对应人员");
            }
        }


        return toAjax(projectInfoService.updateProjectInfo(projectInfo));
    }

    /**
     * 删除项目信息, 删除对应阶段和关联还有【对应子阶段信息】
     */
    @PreAuthorize("@ss.hasPermi('project:info:remove')")
    @Log(title = "项目信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{projectIds}")
    @ApiOperation(value = "删除项目信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult remove(@PathVariable Long[] projectIds) {
        for (Long projectId : projectIds) {
            projectStepService.deleteStepsByProjectId(projectId);
            constructService.remove(new LambdaQueryWrapper<StageConstruct>().eq(StageConstruct::getProjectId,projectId));
            checkFileService.remove(new LambdaQueryWrapper<StageCheckFile>().eq(StageCheckFile::getProjectId,projectId));
            checkController.delAllFile(projectId);
        }
        stageSurveyService.batchDel(Arrays.stream(projectIds).collect(Collectors.toList()));
        return toAjax(projectInfoService.deleteProjectInfoByProjectIds(projectIds));
    }


    private ProjectStep setStep(ProjectStep step) {
        Long[] stepUserIds = projectStepUserService.getAllUserIdsByStepId(step.getStepId());
        LocalDate[] dates = new LocalDate[2];
        dates[0] = step.getStepStartDate();
        dates[1] = step.getStepEndDate();
        if (dates != null && dates.length >= 2 && dates[0] != null) {
            step.setDateArray(dates);
            step.setImplDays((int) ChronoUnit.DAYS.between(dates[0], dates[1]));
        }
        step.setStepUserIds(stepUserIds);

        return step;
    }
}
